<template>
  <div class="input-table" v-clickoutside="handleHide">
    <div class="input-table-input" @click="disabled?this:handleShow()">
      <a-input
          :value="showValue"
          :disabled="disabled"
          class="select-table-input"
          :placeholder="placeholder"
          @change="inputValueChange"
      >
        <a-icon type="bars" style="color: rgba(0,0,0,.45)" slot="suffix"/>
      </a-input>
    </div>
    <div v-bind:class="getTableVisible" style="position: absolute;width: 100%;z-index: 10;white-space: nowrap;overflow-x: auto;">
      <template v-if="searchVisible">
        <a-input v-model="keyWords" placeholder="请输入关键字" style="width: 25%"/>
        <a-button type="primary" @click="search" style="margin:0 6px;" icon="search">搜索</a-button>
        <a-button  @click="reset" icon="sync">重置</a-button>
      </template>
      <a-table
        ref="table"
        size="small"
        :scroll="scroll"
        :columns="columns"
        :dataSource="dataSource"
        :customRow="onCustomRow"
        :pagination="ipagination"
        @change="handleTableChange"
        :rowKey="rowKey"
        show-size-changer
      >
        <span slot="renderSerial" slot-scope="text, record, index">
          {{ index + 1 }}
        </span>
      </a-table>
    </div>
  </div>
</template>

<script>
  import {filterObj, debounce} from '@/utils/util';

  const clickoutside = {
    // 初始化指令
    bind(el, binding, vnode) {
      function documentHandler(e) {
        // 这里判断点击的元素是否是本身，是本身，则返回
        if (el.contains(e.target)) {
          return false
        }
        // 判断指令中是否绑定了函数
        if (binding.expression) {
          // 如果绑定了函数 则调用那个函数，此处binding.value就是handleHide方法
          binding.value(e)
        }
      }

      // 给当前元素绑定个私有变量，方便在unbind中可以解除事件监听
      el.__vueClickOutside__ = documentHandler;
      document.addEventListener('click', documentHandler)
    },
    update() {
    },
    unbind(el, binding) {
      // 解除事件监听
      document.removeEventListener('click', el.__vueClickOutside__);
      delete el.__vueClickOutside__
    }
  };

  export default {
    name: 'ComboGrid',
    props: {
      placeholder: {
        type: String,
        required: false,
        default: ''
      },
      disabled: {
        type: Boolean,
        required: false,
        default: false,
      },
      url: {
        type: String,
        required: false,
        default: ''
      },
      parameter: {},
      columns: {
        type: Array,
        required: false,
        default: () => [],
      },
      value: {
        type: String,
        required: false,
        default: '',
      },
      saveCode: {
        type: String,
        required: false,
        default: 'id',
      },
      showCode: {
        type: String,
        required: false,
        default: 'name',
      },
      sorter: {
        type: Object,
        required: false,
        default: () => {
        },
      },
      queryParams: {
        type: Object,
        required: false,
        default: () => {
        },
      },
      pageSize: {
        type: Number,
        required: false,
        default: 10,
      },
      rowKey: {
        type: String,
        required: false,
        default: "id",
      },
      scroll: {
        type: Object,
        required: false,
        default: function () {
          return {x: 200, y: 500}
        },
      },
      searchVisible: {
        type: Boolean,
        required: false,
        default: false,
      }
    },
    directives: {clickoutside},
    data() {
      return {
        tableVisible: false,
        dataSource: [],
        queryParam:{
         
        },
        keyWords: '',
        /* 分页参数 */
        ipagination: {
          current: 1,
          pageSize: this.pageSize,
          pageSizeOptions: ['5', '10', '15', '20', '30'],
          showSizeChanger: true,
          total: 0,
        },
        isorter: this.sorter, /* 排序参数 */
        showValue: '',//展示值
        saveValue: '',//保存值
        record: {},
        // 存储各个div的style
        style: {
          tableDiv: {
            position: "absolute",
            zIndex: "999",
            backgroundColor: "#ffffff",
            border: "#dedede 1px solid",
            padding: "5"
          },
        },
      }
    },
    mounted(){
    },
    computed: {
      getTableVisible() {
        if (this.tableVisible) {
          return 'showTable';
        } else {
          return 'hideTable';
        }
      },
    },
    model: {
			prop: "value",
			event: "change",
		},
    watch: {
      value: {
        immediate: true,
        handler(val) {
          if (val) {
            this.saveValue = val;
            this.loadData(1)
          } else {
            this.saveValue = '';
            this.showValue = '';
            this.record = {};
            this.$emit('getRecord', {});
            this.loadData(1);
          }
        }
      },
      pageSize: {
        immediate: true,
        handler() {
          this.ipagination.pageSize = this.pageSize
        },

      },
      columns: {
        handler(val) {
          val.forEach((item,index) => {
            if (index !== 0) {
              Object.assign(item, { width: 200, ellipsis: true })
            }
          })
          this.columns = val
        }
      }
    },
    methods: {
      search() {
        let params = this.getQueryParams()
        this.$post(this.url, params).then(res => {
          let newData = this.parseData(res.data)
            if (res.statusCode === 200) {
              this.dataSource = newData.data ? newData.data : newData;
              this.ipagination.total = newData.data ? newData.data.length : newData.length;
            }
        })
      },
      reset() {
        this.keyWords = ''
        let params = this.getQueryParams()
        this.$post(this.url, params).then(res => {
          let newData = this.parseData(res.data)
            if (res.statusCode === 200) {
              this.dataSource = newData.data ? newData.data : newData;
              this.ipagination.total = newData.data ? newData.data.length : newData.length;
            }
        })
      },
      loadData(arg) {
        if (!this.url) {
            return 
          }
          //加载数据 若传入参数1则加载第一页的内容
          if (arg === 1) {
            this.ipagination.current = 1;
          }
          var params = this.getQueryParams();//查询条件
          this.$post(this.url, params).then(res => {
            let newData = this.parseData(res.data)
            if (res.statusCode === 200) {
              this.dataSource = newData.data ? newData.data : newData;
              this.ipagination.total = newData.data ? newData.data.length : newData.length;

              if (this.value) {
                let saveCode = this.saveCode;
                let showCode = this.showCode;
                let data = this.dataSource.find((obj) => obj[saveCode] == this.value);
                this.showValue = data[showCode];
              }
            }
          })
      },
      // JSON格式数据转JS格式
      parseData(data) {
        try {
          // 尝试 JSON.parse 两次
          const parsedData = JSON.parse(JSON.parse(data));
          return parsedData;
        } catch (error) {
          try {
            // 如果报错，再尝试 JSON.parse 一次
            const parsedData = JSON.parse(data);
            return parsedData;
          } catch (error) {
            // 如果再次报错，返回原始数据
            return data;
          }
        }
      },
      getQueryParams() {
        let queryParam = {};
        queryParam = {
          // [this.showCode]: this.showValue,
          keyWords: this.keyWords,
          ...this.parameter,
        };
        if (this.queryParams) {
          Object.assign(queryParam, this.queryParams)
        }
        var param = Object.assign({}, queryParam, this.isorter, this.filters);
        // param.field = this.getQueryField();
        param.pageNo = this.ipagination.current;
        param.pageSize = this.ipagination.pageSize;
        return filterObj(param);
      },
      getQueryField() {
        //TODO 字段权限控制
        var str = "id,";
        this.columns.forEach(function (value) {
          str += "," + value.dataIndex;
        });
        return str;
      },
      handleHide() { // 点击除了页面其他地方关闭车型选择
        this.tableVisible = false;
      },
      handleShow() {
        this.$emit('click', this.saveValue);
        this.loadData(1);
        this.tableVisible = true;
      },
      onCustomRow(record) {
        return {
          props: {},
          on: {
            click: () => {
              this.record = record;
              this.saveValue = this.record[this.saveCode];
              this.showValue = this.record[this.showCode];
              this.$emit('select', this.saveValue);
              this.$emit('input', this.saveValue);
              this.$emit('change', this.saveValue);
              this.$emit('getRecord', this.record);
              this.handleHide();
            },
          },
        };
      },
      inputValueChange(e) {
        this.showValue = e.target.value;
        if (!this.disabled) this.handleShow();
        this.$emit('inputChange', e.target.value);
        if (this.showValue === null || this.showValue === undefined || this.showValue === '') {
          this.clear();
        }
        debounce(() => {
          this.loadData(1)
        }, 500);
      },
      getShowValue() {
        return this.showValue;
      },
      getSaveValue() {
        return this.saveValue;
      },
      clear() {
        this.saveValue = '';
        this.showValue = '';
        this.record = {};
        this.$emit('select', '');
        this.$emit('input', '');
        this.$emit('change', '');
        this.$emit('getRecord', {});
        this.handleHide();
      },
      handleTableChange(pagination, filters, sorter) {
        //分页、排序、筛选变化时触发
        //TODO 筛选
        if (Object.keys(sorter).length > 0) {
          this.isorter.column = sorter.field;
          this.isorter.order = "ascend" == sorter.order ? "asc" : "desc"
        }
        this.ipagination = pagination;
        this.loadData();
      },

      // queryShowValueBySaveValue() {
        // let queryParam = {
        //   [this.saveCode]: this.saveValue,
        // }
        // this.$post(this.url, queryParam).then(res => {
        //   if (res.code == 200) {
        //     this.dataSource = res?.rows;
        //     this.ipagination.total = res.total;
        //     this.dataSource.some((item) => {
        //       if (item) {
        //         if (item[this.saveCode] == this.saveValue) {
        //           this.showValue = item[this.showCode];
        //           this.record = item;
        //           return true;
        //         }
        //       }
        //     })
        //   } else {
        //     this.$message.warning(res.message)
        //   }
        // })
      // },

      // tableDivStyle() {
      //   let style = Object.assign({}, this.style.tableDiv)
      //   let width1 = this.getDivTopLength();
      //   let width2 = this.realTrWidth();
      //   if (width1 > width2) {
      //     style['width'] = width2 + "px";
      //   } else {
      //     style['width'] = width1 + "px";
      //   }
      //   return style
      // },

      //table 列总宽度
      // realTrWidth() {
      //   let calcWidth = 0
      //   this.columns.forEach((column, i) => {
      //     let {type, width} = column
          // 隐藏字段不参与计算
      //     if (typeof width === 'number') {
      //       calcWidth += width
      //     } else if (typeof width === 'string') {
      //       width = width.replace("px", "");
      //       calcWidth += Number(width)
      //     } else {
      //       calcWidth += 120
      //     }
      //   })
      //   return calcWidth
      // },
      //获取指定第v据屏幕右侧宽度
      // getDivTopLength() {
      //   return 600;
      // },
    },
    // 在组件内定义 指定父组件调用时候的传值属性和事件类型
    model: {
      prop: 'value',
      event: 'input'
    }
  }
</script>
<style scoped lang="less">
  .input-table {
    .showTable {
      display: block;
    }
    .hideTable {
      display: none;
    }
    .select-table-input {
      margin-right: 20px;
    }
  }
  /deep/.ant-table-pagination.ant-pagination {
    background-color: rgba(255, 255, 255, 0.5);
    margin-bottom: 50px !important;
    margin-right: 5px !important;
  }
</style>
